#ifndef _core_H
#define _core_H

#include <iostream>
#include <fstream>
#include <sstream>
#include <memory>
#include <cassert>
#include <string.h>
#include <stdlib.h>
#include <zlib.h>
#include <math.h>
#include <vector>
#include <pthread.h>


#include "../../engine/address.hpp"
#include "../../utils/libcache/CacheWriteBack.hpp"

#include "constants.h"
#include "trace.h"


class TLBCMP;

class Core {
    CacheWriteBack<address_t>  *_TLB;
    pthread_mutex_t _mutexTLB;

    uint32_t _pageSize,_lineSize;
    uint32_t _TLBSize;
    uint32_t  _TLBSetBits,_TLBAssocBits;
    uint32_t _TLBHits, _TLBHitInvalidate,_TLBMisses,_TLBReplacements,_TLBEvictions,_TLBAccesses;
    uint32_t _TLBForcedEvictions;
    Trace * _trace;
    uint32_t _appid;
    uint32_t _threadid;
    TLBCMP & _parent;

    public:
       Core(TLBCMP &parent,uint32_t lineSize,uint32_t pageSize, uint32_t TLBSize, uint32_t TLBNways);
        ~Core();
        static void * execute(void * core);
        void reset();
        void access(address_t page);
        void setTrace(Trace *t,uint32_t appid,uint32_t thread);
        void getTraceName(char *dirname);

        inline Trace * getTrace(void);
        void flushPage(address_t evictPage);
        inline uint32_t getApp(){return _appid;}
        inline uint32_t getThreadId(){return _threadid;}
        inline uint32_t getTLBSize(){return _TLBSize;}
        inline uint32_t getTLBAssocBits(){return _TLBAssocBits;}
        inline uint32_t getTLBSetBits(){return _TLBSetBits;}

        inline uint32_t getTLBHits() const {return _TLBHits;}
        inline uint32_t getTLBHitInvalidate() const {return _TLBHitInvalidate;}
        inline uint32_t getTLBMisses() const {return _TLBMisses;}
        inline uint32_t getTLBReplacements() const {return _TLBReplacements;}
        inline uint32_t getTLBEvictions() const {return _TLBEvictions;}
        inline uint32_t getTLBForcedEvictions() const {return _TLBForcedEvictions;}
        inline uint32_t getTLBAccesses() const {return _TLBAccesses;}

};

#endif
